package com.chenbei.erp.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chenbei.erp.domain.PurchaseOrder;
import com.chenbei.erp.domain.PurchaseOrderDetail;
import com.chenbei.erp.enums.PurchaseOrderStatusEnum;
import com.chenbei.erp.mapper.PurchaseOrderMapper;
import com.chenbei.erp.service.IPurchaseOrderDetailService;
import com.chenbei.erp.service.IPurchaseOrderService;
import com.chenbei.erp.vo.req.PurchaseOrderReq;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class PurchaseOrderService extends ServiceImpl<PurchaseOrderMapper, PurchaseOrder> implements IPurchaseOrderService {

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private IPurchaseOrderDetailService purchaseOrderDetailService;

    @Transactional
    @Override
    public void add(PurchaseOrder purchaseOrder) {
        RLock lock = redissonClient.getLock("PurchaseOrder__add");
        try {
            lock.lock();
            long count = count();
            purchaseOrder.setNumber(generateNumber(count));
            if(save(purchaseOrder)) {
                List<PurchaseOrderDetail> details = purchaseOrder.getDetails();
                for (PurchaseOrderDetail purchaseOrderDetail : details) {
                    purchaseOrderDetail.setOrderId(purchaseOrder.getId());
                }
                purchaseOrderDetailService.saveBatch(details);
            }
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }

    @Transactional
    @Override
    public void update(PurchaseOrder purchaseOrder) {
        PurchaseOrder purchaseOrder1 = getById(purchaseOrder.getId());
        if (Objects.equals(purchaseOrder1.getStatus(), PurchaseOrderStatusEnum.DRAFT.getStatus())) {
            purchaseOrder.setNumber(purchaseOrder1.getNumber());
            if(updateById(purchaseOrder)) {
                purchaseOrderDetailService.removeByPurchaseOrderId(purchaseOrder.getId());
                List<PurchaseOrderDetail> details = purchaseOrder.getDetails();
                for (PurchaseOrderDetail purchaseOrderDetail : details) {
                    purchaseOrderDetail.setOrderId(purchaseOrder.getId());
                }
                purchaseOrderDetailService.saveBatch(details);
            }
        }
    }

    @Override
    public Page<PurchaseOrder> pageList(PurchaseOrderReq purchaseOrderReq) {
        LambdaQueryWrapper<PurchaseOrder> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.orderByDesc(PurchaseOrder::getId);
        Page<PurchaseOrder> pageConfig = new Page<>(purchaseOrderReq.getPageNum(), purchaseOrderReq.getPageSize());
        if (StrUtil.isNotBlank(purchaseOrderReq.getName())) {
            lambdaQueryWrapper.like(PurchaseOrder::getName, purchaseOrderReq.getName());
        }
        if (purchaseOrderReq.getStatus() != null && purchaseOrderReq.getStatus() >= 0) {
            lambdaQueryWrapper.eq(PurchaseOrder::getStatus, purchaseOrderReq.getStatus());
        }
        if (purchaseOrderReq.getWarehouseId() != null) {
            lambdaQueryWrapper.eq(PurchaseOrder::getWarehouseId, purchaseOrderReq.getWarehouseId());
        }
        if (purchaseOrderReq.getSupplierId() != null) {
            lambdaQueryWrapper.eq(PurchaseOrder::getSupplierId, purchaseOrderReq.getSupplierId());
        }
        if (purchaseOrderReq.getPurchaseUserId() != null) {
            lambdaQueryWrapper.eq(PurchaseOrder::getPurchaseUserId, purchaseOrderReq.getPurchaseUserId());
        }
        return page(pageConfig, lambdaQueryWrapper);
    }

    @Override
    public PurchaseOrder detail(Long id) {
        PurchaseOrder purchaseOrder = getById(id);
        if (purchaseOrder != null) {
            List<PurchaseOrderDetail> purchaseOrderDetails = purchaseOrderDetailService.listByPurchaseOrderId(id);
            purchaseOrder.setDetails(purchaseOrderDetails);
        }
        return purchaseOrder;
    }

    private String generateNumber(long count) {
        return "PO" + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + String.format("%10d", count+1);
    }
}
